package no.sachmuld.methodcombination.impl.validate;

import java.lang.reflect.Method;
import java.util.Arrays;
import java.util.HashSet;
import java.util.Set;

/**
 *
 */
public class MethodValidationUtils {

    public static boolean validateReturnType(Class targetClass, Class substituteClass) {
        return targetClass.isAssignableFrom(substituteClass);
    }

    public static boolean validateReturnType(Method targetMethod, Method behaviourMethod) {
        return validateReturnType(targetMethod.getReturnType(), behaviourMethod.getReturnType());
    }

    public static boolean validateParameterTypes(Class[] targetParameters, Class[] substituteParameters) {
        if (targetParameters.length != substituteParameters.length) {
            return false;
        } else {
            for (int i = 0; i < targetParameters.length; i++) {
                if (targetParameters[i] != substituteParameters[i]) {
                    return false;
                }
            }
            return true;
        }
    }

    public static boolean validateParameterTypes(Method targetMethod, Method behaviourMethod) {
        return validateParameterTypes(targetMethod.getParameterTypes(), behaviourMethod.getParameterTypes());
    }

    public static boolean validateExceptionTypes(Class[] targetExceptionTypes, Class[] substituteExceptionTypes) {
        outer:
        for (Class substituteExceptionType : substituteExceptionTypes) {
            if (RuntimeException.class.isAssignableFrom(substituteExceptionType)) {
                continue;
            }
            for (Class targetExceptionType : targetExceptionTypes) {
                if (targetExceptionType.isAssignableFrom(substituteExceptionType)) {
                    continue outer;
                }
            }
            return false;
        }
        return true;
    }

    public static boolean validateExceptionTypes(Method targetMethod, Method behaviourMethod) {
        return validateExceptionTypes(targetMethod.getExceptionTypes(), behaviourMethod.getExceptionTypes());
    }

}
